package com.dillon.acr.utils

import android.Manifest
import android.accessibilityservice.AccessibilityService
import android.app.*
import android.app.Notification.PRIORITY_MIN
import android.app.Notification.VISIBILITY_PRIVATE
import android.app.usage.UsageStats
import android.app.usage.UsageStatsManager
import android.content.ComponentName
import android.content.Context
import android.content.Context.POWER_SERVICE
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.provider.ContactsContract
import android.provider.Settings
import android.text.TextUtils
import android.util.Pair
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import com.blankj.utilcode.util.*
import com.dillon.acr.R
import com.dillon.acr.base.App
import com.dillon.acr.base.BAct
import com.dillon.acr.bean.AppInfo
import com.dillon.acr.bean.MediaInfo
import com.dillon.acr.key.CommonK
import com.dillon.acr.services.task.RecorderSer
import java.io.BufferedReader
import java.io.File
import java.io.FileReader
import java.io.IOException
import java.math.BigDecimal
import java.security.KeyPairGenerator
import java.security.NoSuchAlgorithmException
import java.security.SecureRandom
import java.text.DecimalFormat
import java.util.*
import java.util.regex.Pattern


/**
 * @author dillon
 * @description:
 * @date :2019/8/23 14:22
 */
object AUtils {


    // 隐藏应用图标
    fun hideAPP(firstAct: Class<*>) {
        try {
            val packageManager = Utils.getApp().packageManager
            val firstActComponentName = ComponentName(
                AppUtils.getAppPackageName(),
                firstAct.name
            )
            val res = packageManager.getComponentEnabledSetting(firstActComponentName)
            if (res == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT || res == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
                packageManager.setComponentEnabledSetting(
                    firstActComponentName,
                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                    PackageManager.DONT_KILL_APP
                )

            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    // 显示应用图标
    fun showAPP(firstAct: Class<*>) {
        try {
            val packageManager = Utils.getApp().packageManager
            val firstActComponentName = ComponentName(
                AppUtils.getAppPackageName(),
                firstAct.name
            )
            val res = packageManager.getComponentEnabledSetting(firstActComponentName)
            if (res == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT || res == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
            } else {
                packageManager.setComponentEnabledSetting(
                    firstActComponentName,
                    PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
                    PackageManager.DONT_KILL_APP
                )

            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    //获取App启动名，带包名
    fun appLauncherName(pkg: String): String? {
        var packageinfo: PackageInfo? = null
        try {
            packageinfo =
                Utils.getApp().packageManager.getPackageInfo(pkg, 0)
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        if (packageinfo == null) {
            return null
        }
        // 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent
        val resolveIntent = Intent(Intent.ACTION_MAIN, null)
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER)
        resolveIntent.setPackage(packageinfo.packageName)
        // 通过getPackageManager()的queryIntentActivities方法遍历
        val resolveInfoList =
            Utils.getApp().packageManager
                .queryIntentActivities(resolveIntent, 0)
        for (resolveInfo in resolveInfoList) {
            LogUtils.v("resolveInfo:$resolveInfo")
        }
        val resolveInfo = resolveInfoList.iterator().next()
        if (resolveInfo != null) { // packagename = 参数packname
            val packageName = resolveInfo.activityInfo.packageName
            // 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式：packagename.mainActivityname]
            val className = resolveInfo.activityInfo.name
            return resolveInfo.activityInfo.name
        }
        return null
    }


    //APP风格
    fun appStyle(act: BAct) {
        try {
            //设置状态栏透明并高亮，即白底黑字
            BarUtils.setStatusBarColor(act, Color.argb(0, 0, 0, 0))
            BarUtils.setStatusBarLightMode(act, true)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


    fun makeNotification(context: Service, mChannelId: String, mChannelName: String) {
        try {
            val manager =
                Utils.getApp().getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val channel = NotificationChannel(
                    mChannelId, mChannelName,
                    NotificationManager.IMPORTANCE_NONE
                )
                manager.createNotificationChannel(channel)
                val notification = Notification.Builder(context, mChannelId)
                    .setSmallIcon(R.mipmap.ic_logo)
                    .setAutoCancel(true)
                    .setVisibility(VISIBILITY_PRIVATE)
                    .setPriority(PRIORITY_MIN)
                    .build()
                context.startForeground(1, notification)
            } else {
                val nb = NotificationHelper(context).getNotification("", "")
                nb.setDefaults(Notification.DEFAULT_ALL)
                manager.notify(1, nb.build())
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


    //检测悬浮窗权限
    fun checkDrawOverlaysPermission(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            PermissionUtils.isGrantedDrawOverlays()
        } else {
            true
        }
    }


    //忽略电池优化
    fun ignoreBatteryOptimization(activity: Activity) {
        val powerManager = activity.getSystemService(POWER_SERVICE) as PowerManager?
        val hasIgnored = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            powerManager!!.isIgnoringBatteryOptimizations(activity.packageName)
        } else {
            true
        }
        if (!hasIgnored) {
            val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
            intent.data = Uri.parse("package:" + activity.packageName)
            activity.startActivity(intent)
        }
    }

    //查看其它应用使用情况
    fun checkUsagePermission(context: Context): Boolean {
        val appOpsManager = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
        val mode = appOpsManager.checkOpNoThrow(
            AppOpsManager.OPSTR_GET_USAGE_STATS,
            android.os.Process.myUid(),
            context.packageName
        )
        return mode == AppOpsManager.MODE_ALLOWED

    }

    fun startCommonService(cls: Class<*>) {
        //     if (!isNotificationEnabled(Utils.getApp())) {
        val mIntent = Intent(Utils.getApp(), cls)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Utils.getApp().startForegroundService(mIntent)
        } else {
            Utils.getApp().startService(mIntent)
        }
//        } else {
//            LogUtils.e("此服务，不允许通知栏显示通知！")
//        }
    }

    fun startCommonServiceWithoutNotice(cls: Class<*>) {
        if (!NotificationUtils.areNotificationsEnabled()) {
            val mIntent = Intent(Utils.getApp(), cls)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                Utils.getApp().startForegroundService(mIntent)
            } else {
                Utils.getApp().startService(mIntent)
            }
        } else {
            LogUtils.e("此服务，不允许通知栏显示通知！")
        }
    }

    //此服务，需要不开启通知，且符合条件才能开启
    fun startCommonService(cls: Class<*>, otherPermission: Boolean) {
        if (otherPermission && !NotificationUtils.areNotificationsEnabled()
        ) {
            val mIntent = Intent(Utils.getApp(), cls)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                Utils.getApp().startForegroundService(mIntent)
            } else {
                Utils.getApp().startService(mIntent)
            }
        } else {
            LogUtils.e("不符合条件，无法启动服务！")
        }
    }

    fun stopCommonService(cls: Class<*>): Boolean {
        val intent = Intent(Utils.getApp(), cls)
        return Utils.getApp().stopService(intent)
    }


    /**
     * 跳转设置界面
     */
    fun goAppSetting(context: Context) {
        val intent = Intent()
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        intent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"
        intent.data = Uri.fromParts("package", context.packageName, null)
        context.startActivity(intent)

    }

    //打开手机通知设置页面
    fun goAppNotificationSetting(context: Context) {
        if (RomUtils.isXiaomi()) {
            goAppSetting(context)
        } else {
            val intent = Intent()
            if (Build.VERSION.SDK_INT >= 26) {
                intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
                intent.putExtra("android.provider.extra.APP_PACKAGE", context.packageName)
            } else {
                intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
                intent.putExtra("app_package", context.packageName)
                intent.putExtra("app_uid", context.applicationInfo.uid)
            }
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            context.startActivity(intent)
        }

    }


    //获取前台应用
    fun getForegroundApp(context: Context): String? {
        val endTime = System.currentTimeMillis()//结束时间
        val statTime = endTime - 1 * 60 * 60 * 1000//开始时间
        val usageStatsManager =
            context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
        val usageStatsList =
            usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, statTime, endTime)
        if (usageStatsList == null || usageStatsList.isEmpty()) {
            return null
        }
        val usageStatsMap = TreeMap<Long, UsageStats>()
        for (usageStats in usageStatsList) {
            usageStatsMap[usageStats.lastTimeUsed] = usageStats
        }
        if (usageStatsMap.isEmpty()) {
            return null
        }
        return usageStatsMap[usageStatsMap.lastKey()]?.packageName
    }

    private fun getAppInfo(pm: PackageManager, pi: PackageInfo?): AppInfo? {
        if (pi == null) return null
        val appInfo = AppInfo()
        val ai = pi.applicationInfo
        appInfo.appPkg = pi.packageName
        appInfo.appName = ai.loadLabel(pm).toString()
        appInfo.packagePath = ai.sourceDir
        appInfo.firstInstallTime = pi.firstInstallTime
        appInfo.lastUpdateTime = pi.lastUpdateTime
        appInfo.versionName = pi.versionName
        appInfo.versionCode = pi.versionCode
        appInfo.isSystem = ApplicationInfo.FLAG_SYSTEM and ai.flags != 0
        return appInfo
    }

    //获取手机上所有APP列表
    private fun getAppInfoList(): List<AppInfo>? {
        val appInfoList = mutableListOf<AppInfo>()
        val pm = Utils.getApp().packageManager ?: return null
        val installedPackages = pm.getInstalledPackages(0)
        for (pi in installedPackages) {
            val ai = getAppInfo(pm, pi) ?: continue
            appInfoList.add(ai)
        }
        return appInfoList
    }

    //获取非系统APP列表
    fun notSystemAppInfoList(): MutableList<AppInfo> {
        val appInfoList = getAppInfoList()
        val appInfoListNew = mutableListOf<AppInfo>()
        if (appInfoList != null && appInfoList.isNotEmpty()) {
            for (app in appInfoList) {
                if (!app.isSystem) {
                    appInfoListNew.add(app)
                }
            }
        }
        return appInfoListNew
    }

    fun notSystemAppNameList(): MutableList<String> {
        val appInfoList = notSystemAppInfoList()
        val appNameList = mutableListOf<String>()
        if (appInfoList.size > 0) {
            for (appInfo in appInfoList) {
                appNameList.add(appInfo.appName + "")
            }
        }
        return appNameList
    }

    fun isEmail(email: String?): Boolean {
        if (null == email || "" == email) return false
        //Pattern p = Pattern.compile("\\w+@(\\w+.)+[a-z]{2,3}"); //简单匹配
        val p = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*")//复杂匹配
        val m = p.matcher(email)
        return m.matches()
    }


    //打开设置权限页面
    fun openNotificationListenSettings(context: Context) {
        try {
            val intent: Intent =
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
                    Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)
                } else {
                    Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")
                }
            context.startActivity(intent)
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }


    //检测获取系统通知权限
    fun isNotificationListenerEnabled(context: Context): Boolean {
        val packageNames = NotificationManagerCompat.getEnabledListenerPackages(context)
        return packageNames.contains(context.packageName)
    }


    //true为打开，false为关闭
    private fun isScreenOn(): Boolean {
        val powerManager = Utils.getApp().getSystemService(POWER_SERVICE) as PowerManager
        return powerManager.isInteractive
    }

    //当前的屏幕锁有五种设置，分别是没有设置屏幕锁，滑动解锁，图案解锁，PIN码解锁，密码解锁。
//如果没有设置屏幕锁，返回值会一直为true。如果用户设置了屏幕锁（包括后四种锁中的任何一种），屏幕不亮时返回false，屏幕亮时，解锁前返回false，解锁后返回true
    private fun isUserPresent(): Boolean {
        val keyguardManager =
            Utils.getApp().getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
        return !keyguardManager.isKeyguardLocked

    }

    fun isScreenOnUserPresent(): Boolean {
        return isUserPresent() && isScreenOn()
    }

    fun encryptRSA(data: String?): ByteArray? {
        if (data == null) {
            return null
        }
        val keySize = 1024
        return EncryptUtils.encryptRSA(
            data.toByteArray(),
            EncodeUtils.base64Decode(CommonK.PUBLIC_KEY.toByteArray()),
            keySize,
            "RSA/None/PKCS1Padding"
        )
    }

    fun decryptRSA(encryptData: ByteArray?): String? {
        if (encryptData == null) {
            return null
        }
        val keySize = 1024
        val decryptData = EncryptUtils.decryptRSA(
            encryptData,
            EncodeUtils.base64Decode(CommonK.PRIVATE_KEY.toByteArray()),
            keySize,
            "RSA/None/PKCS1Padding"
        )
        return EncodeUtils.base64Encode2String(decryptData)
    }

    fun encryptRSA2String(data: String?): String? {
        if (data == null) {
            return null
        }
        val keySize = 1024
        val encryptData = EncryptUtils.encryptRSA(
            data.toByteArray(),
            EncodeUtils.base64Decode(CommonK.PUBLIC_KEY.toByteArray()),
            keySize,
            "RSA/None/PKCS1Padding"
        )
        return EncodeUtils.base64Encode2String(encryptData)
    }

    //生成密钥对   keySize = 1024、2048
    @Throws(NoSuchAlgorithmException::class)
    fun genKeyPair(size: Int): Pair<String, String> {
        val secureRandom = SecureRandom()

        val keyPairGenerator = KeyPairGenerator.getInstance("RSA")

        keyPairGenerator.initialize(size, secureRandom)

        val keyPair = keyPairGenerator.generateKeyPair()

        val publicKey = keyPair.public

        val privateKey = keyPair.private

        val publicKeyBytes = publicKey.encoded
        val privateKeyBytes = privateKey.encoded

        val publicKeyBase64 = EncodeUtils.base64Encode2String(publicKeyBytes)
        val privateKeyBase64 = EncodeUtils.base64Encode2String(privateKeyBytes)

        return Pair.create(publicKeyBase64, privateKeyBase64)
    }


    /**
     * 判断文件大小处于限制内
     *
     * @param fileLen 文件长度
     * @param fileSize 限制大小
     * @param fileUnit 限制的单位（B,K,M,G）
     * @return
     */
    fun checkFileSizeIsLimit(fileLen: Long?, fileSize: Int, fileUnit: String): Boolean {
        var fileSizeCom = 0.0
        when {
            "B" == fileUnit.toUpperCase(Locale.getDefault()) -> fileSizeCom = fileLen!!.toDouble()
            "K" == fileUnit.toUpperCase(Locale.getDefault()) -> fileSizeCom =
                fileLen!!.toDouble() / 1024
            "M" == fileUnit.toUpperCase(Locale.getDefault()) -> fileSizeCom =
                fileLen!!.toDouble() / (1024 * 1024)
            "G" == fileUnit.toUpperCase(Locale.getDefault()) -> fileSizeCom =
                fileLen!!.toDouble() / (1024 * 1024 * 1024)
        }
        return fileSizeCom <= fileSize

    }

    //获取相机程序列表
    fun getCameraList(): MutableList<String>? {
        val cameraList = mutableListOf<String>()
        val intent = Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE)
        val resolveInfoList = Utils.getApp().packageManager.queryIntentActivities(
            intent,
            PackageManager.MATCH_DEFAULT_ONLY
        )
        if (resolveInfoList.size == 0) {
            LogUtils.v("no Camera")
            return null
        }
        for (i in resolveInfoList.indices) {
            val activityInfo = resolveInfoList[i].activityInfo
            cameraList.add(activityInfo.packageName)
        }
        return cameraList
    }

    fun isCameraTarget(pkg: String?): Boolean {
        val list = getCameraList()
        if (pkg == null || list.isNullOrEmpty()) {
            return false
        }
        for (i in list.indices) {
            if (pkg == list[i]) {
                return true
            }
        }
        return false
    }

    //获取浏览器包名，默认返回一个
    private fun getBrowserList(): MutableList<String>? {
        val browserList = mutableListOf<String>()
        val intent = Intent(Intent.ACTION_VIEW)
        intent.addCategory(Intent.CATEGORY_BROWSABLE)
        intent.data = Uri.parse("http://")
        val resolveInfoList = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Utils.getApp().packageManager.queryIntentActivities(
                intent,
                PackageManager.MATCH_ALL
            )
        } else {
            Utils.getApp().packageManager.queryIntentActivities(
                intent,
                PackageManager.MATCH_DEFAULT_ONLY
            )
        }
        if (resolveInfoList.size == 0) {
            LogUtils.v("no browser")
            return null
        }
        for (i in resolveInfoList.indices) {
            val activityInfo = resolveInfoList[i].activityInfo
            browserList.add(activityInfo.packageName)

        }
        return browserList
    }

    //判断是否浏览器
    fun isBrowser(pkg: String?): Boolean {
        val list = getBrowserList()
        if (pkg == null || list.isNullOrEmpty()) {
            return false
        }
        for (i in list.indices) {
            if (pkg == list[i]) {
                return true
            }
        }
        return false
    }

    fun isBrowserTarget(pkg: String?): Boolean {
        val list = CommonK.BROWSER_TARGET
        if (pkg == null || list.isNullOrEmpty()) {
            return false
        }
        for (i in list.indices) {
            if (pkg == list[i]) {
                return true
            }
        }
        return false
    }

    //判断是否是截图目标APP
    fun isChatTarget(pkg: String?): Boolean {
        val list = CommonK.CHAT_TARGET
        if (pkg == null || list.isNullOrEmpty()) {
            return false
        }
        for (i in list.indices) {
            if (pkg == list[i]) {
                return true
            }
        }
        return false
    }

    //判断辅助服务是否开启
    fun isAccessibilitySettingsOn(
        clazz: Class<out AccessibilityService>
    ): Boolean {
        var accessibilityEnabled = 0
        val service = Utils.getApp().packageName + "/" + clazz.canonicalName
        try {
            accessibilityEnabled = Settings.Secure.getInt(
                Utils.getApp().applicationContext.contentResolver,
                Settings.Secure.ACCESSIBILITY_ENABLED
            )
        } catch (e: Settings.SettingNotFoundException) {
            e.printStackTrace()
        }

        val mStringColonSplitter = TextUtils.SimpleStringSplitter(':')
        if (accessibilityEnabled == 1) {
            val settingValue = Settings.Secure.getString(
                Utils.getApp().applicationContext.contentResolver,
                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
            )
            if (settingValue != null) {
                mStringColonSplitter.setString(settingValue)
                while (mStringColonSplitter.hasNext()) {
                    val accessibilityService = mStringColonSplitter.next()
                    if (accessibilityService.equals(service, ignoreCase = true)) {
                        return true
                    }
                }
            }
        }
        return false
    }


    fun getProcessName(pid: Int): String? {
        var reader: BufferedReader? = null
        try {
            reader = BufferedReader(FileReader("/proc/$pid/cmdline"))
            var processName: String = reader.readLine()
            if (!TextUtils.isEmpty(processName)) {
                processName = processName.trim { it <= ' ' }
            }
            return processName
        } catch (throwable: Throwable) {
            throwable.printStackTrace()
        } finally {
            try {
                reader?.close()
            } catch (exception: IOException) {
                exception.printStackTrace()
            }
        }
        return null
    }

    //字符串简单加密，翻转，+8 -8
    val Type_Encrypt = 1
    val Type_Decrypt = 2
    fun simpleEncryptAndDecryptString(data: String?, type: Int): String? {
        if (data.isNullOrBlank()) return null
        val newData = StringBuilder(data.trim()).reverse()
        if (newData.isBlank()) return null
        val s = StringBuilder()
        if (Type_Encrypt == type) {
            for (element in newData) {
                var a = element.toInt()
                a += 8
                s.append(a.toChar())
            }
            return s.toString()
        }
        if (Type_Decrypt == type) {
            for (element in newData) {
                var a = element.toInt()
                a -= 8
                s.append(a.toChar())
            }
            return s.toString()
        }
        return null
    }

    fun isDevPass(inputPass: String): Boolean {
        val cryptPass =
            simpleEncryptAndDecryptString(
                inputPass,
                Type_Encrypt
            )
        if (cryptPass == CommonK.devPass) {
            return true
        }
        return false
    }

    fun isDevEmail(): Boolean {
        val cryptEmail =
            simpleEncryptAndDecryptString(
                LocalCacheUtils.getLocalUser()?.mDevEmail,
                Type_Encrypt
            )
        if (cryptEmail == CommonK.devEmail) {
            return true
        }
        return false
    }


    //文件大小展示
    fun fileSizeShowString(size: Long): String {
        var fileSize = BigDecimal(size)
        val param = BigDecimal(1024)
        var count = 0
        while (fileSize > param && count < 5) {
            fileSize = fileSize.divide(param)
            count++
        }
        val df = DecimalFormat("#.##")
        var result = df.format(fileSize) + ""
        when (count) {
            0 -> result += "B"
            1 -> result += "KB"
            2 -> result += "MB"
            3 -> result += "GB"
            4 -> result += "TB"
            5 -> result += "PB"
        }
        return result
    }

    var sortTypeDescending = 2 //2：risk降序
    var sortTypeDefault = 1 //1：risk升序
    fun getSortGroupList(
        sortType: Int,
        oldList: MutableList<MediaInfo>?
    ): MutableList<MediaInfo> {
        val targetList = mutableListOf<MediaInfo>()
        if (!oldList.isNullOrEmpty()) {
            for (group in oldList) {
                targetList.add(group)
            }
        }
        if (targetList.isNotEmpty()) {
            when (sortType) {
                sortTypeDescending -> {
                    targetList.sortByDescending { FileUtils.getFileLastModified(it.file) }
                }
                sortTypeDefault -> {
                    targetList.sortBy { FileUtils.getFileLastModified(it.file) }
                }
                else -> {
                    return targetList

                }
            }
        }
        return targetList
    }

    fun openAccessibility() {
        if (!isAccessibilitySettingsOn(RecorderSer::class.java)) {
            val intent = Intent(
                Settings.ACTION_ACCESSIBILITY_SETTINGS
            )
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            Utils.getApp().startActivity(intent)
        }
    }

    fun checkPasswordToUnLock(): Boolean {
        val keyguardManager =
            Utils.getApp().getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
        keyguardManager.isKeyguardSecure
        return keyguardManager.isKeyguardSecure
    }

    //启用组件
    fun enableComponent(componentName: ComponentName?) {
        if (null == componentName) {
            return
        }
        val pm = Utils.getApp().packageManager
        val state: Int = pm.getComponentEnabledSetting(componentName)
        if (state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
            //已经启用
            return
        }
        pm.setComponentEnabledSetting(
            componentName,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP
        )
    }

    //禁用组件
    fun disableComponent(componentName: ComponentName?) {
        if (null == componentName) {
            return
        }
        val pm = Utils.getApp().packageManager
        val state: Int = pm.getComponentEnabledSetting(componentName)
        if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
            //已经禁用
            return
        }
        pm.setComponentEnabledSetting(
            componentName,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP
        )
    }

    fun shareMediaFile(context: Context, mediaInfo: MediaInfo?) {
        if (mediaInfo == null) return
        ToastUtils.showShort("ShareMedia")

    }

    fun openVideo(context: Context, mediaInfo: MediaInfo?) {
        if (mediaInfo == null) return
        if (!mediaInfo.path!!.endsWith(".mp4")) return
        val intent = Intent()
        intent.action = Intent.ACTION_VIEW
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        intent.setDataAndType(UriUtils.file2Uri(mediaInfo.file!!), "video/*")
        context.startActivity(intent)
    }

    //检测电源优化是否已经忽略
    fun checkIgnoreBatteryOptimization(): Boolean {
        val powerManager = Utils.getApp().getSystemService(Context.POWER_SERVICE) as PowerManager?
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            powerManager!!.isIgnoringBatteryOptimizations(Utils.getApp().packageName)
        } else {
            true
        }

    }

    //检测免打扰
    fun checkDoNotDisturb(): Boolean {
        val notificationManager =
            Utils.getApp().getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            notificationManager.isNotificationPolicyAccessGranted
        } else {
            true
        }
    }

    //检测悬浮窗
    fun checkOverDraw(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            PermissionUtils.isGrantedDrawOverlays()
        } else {
            true
        }
    }

    fun checkInstallFromGoogle(): Boolean {
        try {
            val installer = Utils.getApp().packageManager
                .getInstallerPackageName(Utils.getApp().packageName)
            LogUtils.d(installer)
            if (installer == "com.android.vending") {
                // 确保是google play 安装的
                LogUtils.d("google play")
                return true
            }
        } catch (e: java.lang.Exception) {
            LogUtils.e(e.toString())
        }
        return false
    }

    fun simpleLog(logStr: String) {
    }

    //偏移
    fun simpleEncrypt(str: String) {
        val s = java.lang.StringBuilder()
        val c = str.toCharArray()
        for (element in str) {
            var a = element.toInt()
            a += 7
            s.append(a.toChar())
        }
    }

    fun simpleDecrypt(str: String) {
        val d = java.lang.StringBuilder()
        val c2 = str.toCharArray()
        for (element in str) {
            var b = element.toInt()
            b -= 7
            d.append(b.toChar())
        }
    }

    fun getMediaInfoListByType(selectType: String): MutableList<MediaInfo> {
        var fileList = mutableListOf<File>()
        val tempMediaInfoList = mutableListOf<MediaInfo>()

        when (selectType) {
            CommonK.Type_Media_Audio -> {
                fileList = FileUtils.listFilesInDir(App.saveAudioDir)
                LogUtils.i("AudioListSize:" + fileList.size)
            }
        }

        for (file in fileList) {
            val filePath = file.absolutePath
            if (filePath.endsWith(".jpg") || filePath.endsWith(".mp4") || filePath.endsWith(".m4a") || filePath.endsWith(
                    ".wav"
                )
            ) {
                val group = MediaInfo()
                group.file = file
                group.setOtherParams(file)
                tempMediaInfoList.add(group)
            }
        }
        return getSortGroupList(sortTypeDescending, tempMediaInfoList)
    }

    fun getMediaInfoListByPage(
        sourceList: MutableList<MediaInfo>?,
        pageSize: Int,
        page: Int?        //page从1开始 0或空都重置为1
    ): MutableList<MediaInfo>? {
        val tempPage = if (0 == page || null == page) {
            1
        } else {
            page
        }
        if (sourceList.isNullOrEmpty()) return null
        val allDataSize = sourceList.size
        val targetList = mutableListOf<MediaInfo>()
        if (allDataSize - pageSize * (tempPage - 1) < pageSize) {
            for (index in pageSize * (tempPage - 1) until allDataSize) {
                targetList.add(sourceList[index])
            }
        } else {
            for (index in pageSize * (tempPage - 1) until pageSize * tempPage) {
                targetList.add(sourceList[index])
            }
        }
        return targetList
    }


    fun isPro(): Boolean {
        if (CommonK.proPkg == AppUtils.getAppPackageName()) {
            return true
        }
        if (1000 > LocalCacheUtils.getProExp()) {
            return false
        }
        return true
    }

    fun saveMediaExternal(context: Context, mediaInfo: MediaInfo?) {
        if (null == mediaInfo) return
        ToastUtils.showShort("SaveMedia")
    }

    // 通过phone手机号关联Contacts联系人的显示名字
    fun getPersonNameByPhone(phone: String?): String? {
        if (ContextCompat.checkSelfPermission(
                Utils.getApp(),
                Manifest.permission.READ_CALL_LOG
            ) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
                Utils.getApp(),
                Manifest.permission.READ_CONTACTS
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            LogUtils.v("缺少READ_CALL_LOG|READ_CONTACTS权限！")
            return null
        }
        if (phone == null || phone === "") {
            return null
        }

        var personName: String? = null
        val projection = arrayOf(
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
            ContactsContract.CommonDataKinds.Phone.NUMBER
        )

        val uriPerson = Uri.withAppendedPath(
            ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI,
            phone
        )  // phone 手机号过滤
        val cursor = Utils.getApp().contentResolver.query(uriPerson, projection, null, null, null)
        if (cursor != null && cursor.moveToFirst()) {
            personName =
                cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
        }
        cursor?.close()
        return personName
    }

    fun isValidFileName(fileName: String?): Boolean {
        if (fileName == null || fileName.length > 255) {
            return false
        }
        val patternStr =
            "[^\\s\\\\/:\\*\\?\\\"<>\\|](\\x20|[^\\s\\\\/:\\*\\?\\\"<>\\|])*[^\\s\\\\/:\\*\\?\\\"<>\\|\\.]$"
        val regex = Regex(patternStr)
        return fileName.matches(regex)
    }
}


